Hello, We have had quite a peaceful week here in the office. Last night we went out for a burger and a beer as a last meal with Ernestas before he flies back home for another few months. It was also quite nostalgic, as we went to a place that we used to go to frequently near our old office, and the staff still remembered us.
Fluid mixing saga Dominik Hello Factorians, Today I would like to talk to you about my favourite subject - fluid mixing and its prevention. It is a new mechanic introduced in 0.17 that seemed quite simple at first, but has been giving me nightmares ever since. A while ago I took on the task of updating the fluid system (FFF-260). The way it works in 0.16 is that the fluid boxes (the thing that holds the fluid and is contained in entities like pipes or refineries) had no organisation whatsoever except their connections. They would sit there and do nothing and then once per update send fluid somewhere. It had it's issues especially with symmetry, and when you happened to put some fluid where it did not belong, you could end up requiring major demolition works. My task was to develop a better algorithm to move the fluids, and a very very optional side task I had in mind was to do something about the fluids getting to wrong places and mixing. We started by organizing the fluid boxes into systems (connected FBs make a system) managed by a special fluid manager, and optimizing the heck out of it (FFF-271). Soon after, I started working on the new algorithm and anti fluid-mixing. Until then nobody really considered preventing the fluid mixing seriously as it did not seem possible. But when I thought about it, it did not seem that hard. The idea is to simply not allow any action that would lead to fluids getting where they are not supposed to go. When you build a steam pipeline, you should not need nor want it to touch another fluid. In principle, it would only require a few quite realistic mechanisms: A connected block of fluid boxes would either be fluid-free, or it would be locked to one fluid. Two such blocks can connect only if they are compatible - either one has no fluid lock, or they have the same fluid. An assembler can only set a recipe if it is compatible with the fluid locks on its fluid boxes. Have a migration from old saves that can contain mixing. By creating the fluid systems right before, number 1 was almost finished and we only needed to assign the lock. It would be set either by a fluid, or by a 'filter', which is a fluidbox that is set to use a fluid - such as a water pump using water, or assembler having some inputs/outputs given by a recipe. After a while I had both the fluid algorithm and the mixing done (FFF-274). The mixing was not that easy (like 5x more complicated) but it worked pretty well. As for the fluid algorithm, V453000 and Twinsen found some issues with waves on a macro scale, and because it was right before releasing the 0.17 experimental, we decided to hold it off on it for the time being (we have a new version now that seems okay, but has to wait for 0.17 becoming stable first). The mixing made it through though and seemed quite finished. It turned out that the work on it was at most one tenth complete. Some difficulties appeared already before the initial release, but that was only a hint of what would come later. One by one, then ten by ten, bugs started coming. The problem is that as often as not, they were not just little issues with simple fixes. Instead, over and over, they turned the current solution on its head and the code had to be completely rewritten in order to account for the new case. As of now, almost exactly half a year and many rewrites later, it is still not fully bug free. The number one issue was with Assembling machines. It turned out that their code was pretty messy and does not simply allow the checks I needed, so it had to be refactored. The next problem was that the check was not only required when setting a recipe on an existing assembler - as I naively thought - but in about one million different situations I would not dream existed. Building a fixed recipe assembler. Reviving an assembler. Rotating. Blueprint of an assembler. Blueprint with a recipe and a rotation placed over a ghost with a non-default rotation during a full moon. Teleport. Script building. Copy-paste settings. Any combination of these. Pretty much every case would go through different paths in the code and behave entirely differently. Fixing one would break another and so tons of tests had to be written. When these cases finally worked, it turned out that doing these operations when they fail (e.g. can’t rotate because it would cause mixing) brings another wave of issues. And then mods come and the complexity multiplies. All this, although in a more simple form, had to be done for all other entities that can use fluid too, such as inserters (mods...). Another number one issue are underground connections. When playing, you would not think twice about them but on a closer look they are all but simple. They have this (cough) uncomfortable feature (want to shoot myself) that you can build another underground pipe between them (or take it out) and a complex reconnection logic jumps in. It means that based on building order, connections are established and reestablished differently. This is a big thing when building a blueprint with many pipes, or loading a save game. But the largest issue is one tiny corner case with huge implications. Have two underground pipes that have different fluids, but are split by a third, and it gets removed. Until now mixing was theoretically completely avoidable, but here it was and there was nothing to stop it. As a result, a new concept is introduced - a blocked connection. An underground connection that would normally connect but can’t. Establishing it is the easier part. But when does it get fixed? An entity miles away gets rotated, that splits a fluid system, disconnecting the blocked connection from a fluid filter on the other side, and the connection should unblock. But even something as simple as a rotation contains fluid fixes and re-establishing of fluid boxes and if it fails, it still fixes the blocked connection in the process and it can’t be undone... You get the picture. And we are still talking about underground pipes, while anything can have underground connections, including said assemblers, which the previous code did not consider at all. The complexity just goes deeper and deeper, and Rseding is probably right that we should have never gone this way at all. So the bug fixing has been basically running in circles - clearing one batch of bugs, thinking that those were the last ones and the ordeal is finally over, only to find another batch (ideally from some bizzare modder idea) a few days later. Many times I wished that mods never existed. Nor multiplayer, or any players at all for that matter. About two months ago all seemed really fine, with basically no reports and just a few crashes in the automated crash reports. At that moment another nightmare materialized in the form of a talented volunteer bug tester named boskid, who took on a personal crusade to break the fluids to dust (I actually imagine him sitting in his dark room with evil laughter, dreaming about making my next day worse than the previous). In all seriousness, he has done a great deal of work with his bug testing, creating bizzare modded cases and testing scripts, and deserves a big thanks. He is actually coming to our offices next week, so follow the news for reports of developers falling out of windows. An example of a nice configuration he found (and I can’t fix). The whole time we were taking the offensive approach to mixing - crash the game when it happens - so that we know about bugs to fix them. Recently we have decided to put a stop to it and have the mixing automatically fix itself once it is detected, eyeing the end of this episode. Right now I have 3 mixing bugs on the list and I am sure those are the last, and mixing will be done (lying to myself is a way to cope with it) and the new fluid algorithm can come soon after :).
Hello, Another week has elapsed, which brings us another week deeper into the declining weather of autumn.
A few bugs left... WoW classic has been released, which means several of our top men have taken time off to spend hours raiding and having fun in Azeroth. This isn't great timing, as a few new bugs related to train signals appeared. We want to get these bugs solved before we do another release (another stable candidate). As it turns out, the only person with the skillset to fix these specific train signal bugs is also deep into levelling his Priest... (Kov on Pyrewood Village) We are still making the rest of the preparations for the stable release. We have started writing up the stable annoucement blog post, and have produced a 0.17 postcard image. Other than the few more critical rail bugs, there doesn't look like there is much else to block the stable release, on the forum we are down to 27 bugs. Since there are so few bugs left to deal with, some of the team has starting working on 'post-stable' features. Wheybags is working on the new campaign, Oxyd is diving into some detailed pathfinder improvements, and Rseding has started work on some particle optimizations. We will delve deeper into these topics and more in future FFFs, as we always love to do.
The boring phase of bug-fixing is still going, slowly but surely. Stable should be released next week, but with some people on vacation (Ben, Jitka, kovarex, Klonan, Sanqui) and with the release of WoW Classic, it might get slowed down a bit. (By the way, some of us will be playing on Pyrewood Village, Alliance, so if you want to have the chance of meeting Twinsen, kovarex or dominik while leveling, you can join that server). So since there's not much happening, this week we decided to explore some unpopular or controversial opinions about the game from within the team. In Wube we don't have a very strict management structure, everyone is free to have ideas and opinions about almost all aspects of the game. This means that with almost every change we argue and discuss a lot before making a final decision. Sometimes we argue about everything, from the smallest GUI change, to how a major feature should work. This is probably not a bad thing since this means changes are usually well thought out and unpopular ideas or changes don't make it to the game very often. Some people feel quite strongly about their opinions or sometimes the team is very divided on what should we do. Today we'll share some of those opinions and controversies. Keep in mind that these are simply opinions and none of them will actually make it into the game, we are simply sharing them to have an interesting discussion.
Hello, we had a party last night in the office to celebrate the work we have done over the last 6 months on 0.17 stablisation. It was nice to have most of the team together to share some beers and pizza.
Hello, We had a lovely surprise waiting us this Monday, one of our fans had sent us a delicious cake: It didn't last very long... Thank you very much Conn! It certainly helped with the bug fixing push this week.
Warning this Friday facts is about the Introduction scenario, not about anything that will be in Freeplay Factorio. You may want to read previous FFFs (FFF-257, FFF-284) about the Introduction. TLDR: the Stable candidate of the Introduction scenario is now in Experimental please play it and send me your screenshots. Feedback especially on the “freeform endgame” would be greatly appreciated. We have also released a Experimental version of the Demo, be sure to send this link to your friends ASAP. SPOILER WARNING: If you have not yet played the Introduction Scenario, go play it before you read this.
Lua Mod GUI additions Rseding Mod GUIs have been an interesting part of Factorio modding since I started working at Wube. They allow scenarios and mods to add GUIs that look and feel like the base game. When someone new to Factorio modding is introduced to how they function, they almost always have the same questions: Why is mod GUI part of the game state? Why do mod GUIs need to be deterministic? How can I edit the base game GUIs? And then comes the explanation: The actual widgets are not part of the game state and are not deterministic. The part that mods have access to however is. In an environment where mods have to operate deterministically, if a mod is allowed to read some data that data must be deterministic. In that simple bit of logic; if a mod can read the checked state of a checkbox then that checked state needs to be deterministic. If the mod didn't have access to read that state it would need to store the last-known state and update it every time it got the changed event. Try to imagine that: every single mod implementing their own system for remembering last-known-state about GUIs they're using. Instead of leaving that entire mess to mod developers we decided long ago that we would manage that "last-known-state" for them. The basic data about what a given mod wanted to show on screen is recorded so mods can read and change it as they want and not need to be concerned with constantly updating it every time some changed event happens. Additionally it means that the game can use that "last known state" to restore what the player sees if they save, quit, and load the game. That still leaves the last question: "How can I edit the base game GUIs?". Using the above example it's much easier to explain that: as a mod - you can't. The base game GUIs are not implemented using this same system - they're just pure collections of widgets. None of the "last known state" is saved anywhere and it's all lost when saving, quitting, and loading. However, that leaves a divide: we need to implement each widget type through the "CustomGui" system in order for mods to be able to use them. With this latest release I finally figured out a way to do tabbed panes since they're special in how they work compared to everything else. Additionally I figured out a semi-friendly way for mods to put things directly on the screen in a way that the player can drag them around - instead of being limited to some fixed area (left, top, center, etc). Another system which I've been thinking about for quite some time is some way for mods to position GUI elements relative to base game GUIs. For example: a mod wants to add a pane which shows on the left of the character inventory GUI. Currently it's not possible - the base game GUI isn't readable by mods so they can't do anything with it. My idea is some system where a mod can say "I want to add this GUI, and I want it to be shown relative to the character GUI on the left side" and then any time the character GUI is shown it would also show the mod GUI. There are some critical parts to this new system. It needs to: Be easy to expand (either automatically works with all new base game GUIs or works with minimal effort). Not break with simple refactoring. Not cause other programmers trouble by existing. Not prevent base game GUIs from working how they need to work. So far none of it seems impossible. I don't know when I'll have it working, but I'm looking forward to what mods will do with it.
Hello, We are down to 28 bugs on the forum. The last bugs are often the ones we have been putting off for a reason, they generally require some more meaningful changes and decisions. That is why this week we have a lot to discuss.